﻿using System.IO;
using Telerik.Windows.Documents.Fixed.Model;
using Telerik.Windows.Documents.Fixed.Model.Editing;
using Telerik.Windows.Documents.Flow.FormatProviders.Html;
using Telerik.Windows.Documents.Flow.Model;
using System.Linq;
using Telerik.Windows.Documents.Fixed.Model.Editing.Tables;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using System.Collections.Generic;
using Telerik.Windows.Documents.Fixed.Model.ColorSpaces;

namespace Console_4._7._2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            RadFlowDocument htmlDocument;
            HtmlFormatProvider htmlFormatProvider = new HtmlFormatProvider();

            using (Stream input = File.OpenRead("..\\..\\..\\..\\input.html"))
            {
                htmlDocument = htmlFormatProvider.Import(input, null);
            }

            Telerik.Windows.Documents.Flow.Model.Table htmlTable = htmlDocument.EnumerateChildrenOfType<Telerik.Windows.Documents.Flow.Model.Table>().FirstOrDefault();

            if (htmlTable == null)
            {
                System.Console.WriteLine("No table found in the HTML document.");
                return;
            }

            RadFixedDocument pdfDocument = new RadFixedDocument();
            
            // Convert HTML table to PDF tables across multiple pages
            ConvertHtmlTableToPdf(htmlTable, pdfDocument);

            // Save the PDF document
            PdfFormatProvider pdfProvider = new PdfFormatProvider();
            using (Stream output = File.Create("output.pdf"))
            {
                pdfProvider.Export(pdfDocument, output);
            }

            System.Console.WriteLine("PDF document created successfully.");
        }

        static void ConvertHtmlTableToPdf(Telerik.Windows.Documents.Flow.Model.Table htmlTable, RadFixedDocument pdfDocument)
        {
            const double pageMargin = 72; // 1 inch margin
            const double maxTableWidth = 595.2 - (2 * pageMargin); // A4 width minus margins
            const double maxTableHeight = 841.8 - (2 * pageMargin); // A4 height minus margins

            RadFixedPage currentPage = pdfDocument.Pages.AddPage();
            FixedContentEditor currentEditor = new FixedContentEditor(currentPage);
            
            Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table currentPdfTable = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table();
            double currentTableHeight = 0;
            bool isFirstTable = true;

            // Get all rows from the HTML table
            var htmlRows = htmlTable.Rows.ToList();
            
            for (int rowIndex = 0; rowIndex < htmlRows.Count; rowIndex++)
            {
                var htmlRow = htmlRows[rowIndex];
                
                // Create a PDF table row
                Telerik.Windows.Documents.Fixed.Model.Editing.Tables.TableRow pdfRow = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.TableRow();
                
                // Copy cells from HTML row to PDF row
                foreach (var htmlCell in htmlRow.Cells)
                {
                    Telerik.Windows.Documents.Fixed.Model.Editing.Tables.TableCell pdfCell = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.TableCell();
                    
                    // Copy cell content
                    foreach (var block in htmlCell.Blocks)
                    {
                        if (block is Paragraph paragraph)
                        {
                            Block newParagraph = new Block();
                            foreach (var inline in paragraph.Inlines)
                            {
                                if (inline is Run run)
                                {
                                    newParagraph.InsertText(run.Text);
                                }
                            }
                            pdfCell.Blocks.Add(newParagraph);
                        }
                    }
                    
                    // Set cell properties
                    pdfCell.Padding = new Telerik.Windows.Documents.Primitives.Thickness(5);
                    pdfCell.Borders = new TableCellBorders(
                        new Border(1, new RgbColor(0, 0, 0)),
                        new Border(1, new RgbColor(0, 0, 0)),
                        new Border(1, new RgbColor(0, 0, 0)),
                        new Border(1, new RgbColor(0, 0, 0))
                    );
                    
                    pdfRow.Cells.Add(pdfCell);
                }
                
                // Add the row to current table
                currentPdfTable.Rows.Add(pdfRow);
                
                // Calculate estimated row height (simplified calculation)
                double estimatedRowHeight = CalculateEstimatedRowHeight(pdfRow);
                double projectedTableHeight = currentTableHeight + estimatedRowHeight;
                
                // Check if adding this row would exceed page height
                if (projectedTableHeight > maxTableHeight && !isFirstTable)
                {
                    // Remove the last row that doesn't fit
                    currentPdfTable.Rows.RemoveAt(currentPdfTable.Rows.Count - 1);
                    
                    // Draw the current table on the page
                    DrawTableOnPage(currentEditor, currentPdfTable, pageMargin, maxTableWidth);
                    
                    // Create a new page and table
                    currentPage = pdfDocument.Pages.AddPage();
                    currentEditor = new FixedContentEditor(currentPage);
                    currentPdfTable = new Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table();
                    currentTableHeight = 0;
                    
                    // Add the row that didn't fit to the new table
                    currentPdfTable.Rows.Add(pdfRow);
                    currentTableHeight = estimatedRowHeight;
                }
                else
                {
                    currentTableHeight = projectedTableHeight;
                    isFirstTable = false;
                }
            }
            
            // Draw the final table if it has rows
            if (currentPdfTable.Rows.Count > 0)
            {
                DrawTableOnPage(currentEditor, currentPdfTable, pageMargin, maxTableWidth);
            }
        }

        static double CalculateEstimatedRowHeight(Telerik.Windows.Documents.Fixed.Model.Editing.Tables.TableRow row)
        {
            // Simplified height calculation - in a real scenario, you'd need to measure text height
            double baseRowHeight = 25; // Base height for a row
            double maxCellHeight = baseRowHeight;
            
            foreach (var cell in row.Cells)
            {
                double cellHeight = baseRowHeight;
                
                // Add height for each block of content
                foreach (var block in cell.Blocks)
                {
                    cellHeight += 15; // Approximate height per text block
                }
                
                if (cellHeight > maxCellHeight)
                {
                    maxCellHeight = cellHeight;
                }
            }
            
            return maxCellHeight;
        }

        static void DrawTableOnPage(FixedContentEditor editor, Telerik.Windows.Documents.Fixed.Model.Editing.Tables.Table table, double margin, double maxWidth)
        {
            // Set table position
            editor.Position.Translate(margin, margin);
            
            // Set column widths to distribute evenly
            if (table.Rows.Count > 0)
            {
                int columnCount = table.Rows[0].Cells.Count;
                double columnWidth = maxWidth / columnCount;
                
                // Set preferred width for all cells in each column
                for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
                {
                    for (int colIndex = 0; colIndex < table.Rows[rowIndex].Cells.Count && colIndex < columnCount; colIndex++)
                    {
                        table.Rows[rowIndex].Cells[colIndex].PreferredWidth = columnWidth;
                    }
                }
            }
            
            // Draw the table
            editor.DrawTable(table);
        }
    }
}
